﻿namespace MetaProperties.Core
{
    using System;
    using System.Threading;

    /// <summary>
    /// Useful extension methods for synchronization contexts and containers.
    /// </summary>
    public static class SynchronizationContextContainerExtensions
    {
        /// <summary>
        /// Asynchronously invokes to the container's synchronization context.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="method">The method.</param>
        /// <param name="state">The state.</param>
        public static void Post(this ISynchronizationContextContainer container, SendOrPostCallback method, object state)
        {
            container.SynchronizationContext.Post(method, state);
        }

        /// <summary>
        /// Synchronously invokes to the container's synchronization context.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="method">The method.</param>
        /// <param name="state">The state.</param>
        public static void Send(this ISynchronizationContextContainer container, SendOrPostCallback method, object state)
        {
            container.SynchronizationContext.Send(method, state);
        }

        /// <summary>
        /// Asynchronously invokes to the container's synchronization context.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="method">The method.</param>
        public static void Post(this ISynchronizationContextContainer container, Action method)
        {
            container.SynchronizationContext.Post(o => method(), null);
        }

        /// <summary>
        /// Synchronously invokes to the container's synchronization context.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="method">The method.</param>
        public static void Send(this ISynchronizationContextContainer container, Action method)
        {
            container.SynchronizationContext.Send(o => method(), null);
        }

        /// <summary>
        /// Asynchronously invokes to the synchronization context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="method">The method.</param>
        public static void Post(this SynchronizationContext context, Action method)
        {
            context.Post(o => method(), null);
        }

        /// <summary>
        /// Synchronously invokes to the synchronization context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="method">The method.</param>
        public static void Send(this SynchronizationContext context, Action method)
        {
            context.Send(o => method(), null);
        }
    }
}